<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<!-- Line -->
<script id="VertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="FragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    void main(){
        gl_FragColor = vec4(1,1,1,1);
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import Poly from '../js/Poly4.js';
    import { initShaders, CreateProgram } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Geo from '../js/Poly/Geo.js'
    import Mat from '../js/Poly/Mat.js'
    import Obj3D from '../js/Poly/Obj3D.js'
    import Scene from '../js/Poly/Scene.js'


    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl");
    //开始背景遮挡
    // gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    //#endregion


    //创建程序对象
    let program1 = CreateProgram(gl,
        document.querySelector('#VertexShader').innerText,
        document.querySelector('#FragmentShader').innerText);
    let program2 = CreateProgram(gl,
        document.querySelector('#VertexShader').innerText,
        document.querySelector('#FragmentShader').innerText);
    let program3 = CreateProgram(gl,
        document.querySelector('#VertexShader').innerText,
        document.querySelector('#FragmentShader').innerText);

    const scene = new Scene({ gl: gl });

    const perspectiveCamera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const pvM4 = new Matrix4().multiplyMatrices(perspectiveCamera.projectionMatrix, perspectiveCamera.matrixWorldInverse);

    const modelBaseM4 = new Matrix4();
    const [modelScale1, modelScale2, modelScale3] = [1.0, 0.7, 0.4];
    const [modelM4_1, modelM4_2, modelM4_3] = [
        modelBaseM4.clone().multiply(new Matrix4().makeScale(modelScale1, modelScale1, modelScale1)),
        modelBaseM4.clone().multiply(new Matrix4().makeScale(modelScale2, modelScale2, modelScale2)),
        modelBaseM4.clone().multiply(new Matrix4().makeScale(modelScale3, modelScale3, modelScale3)),
    ];

    const cameraController = new CameraController({
        canvas: canvas,
        camera: perspectiveCamera,
        pvMatrix: pvM4,
        rendEvent: rend,
        eye: new Vector3(0, 0, 3),
        lookAt: new Vector3(0, 0, 0)
    });

    let square1, square2, square3;
    const edgeLength = 0.5;
    const nodeSize = 20;

    const squareNode = [
        -edgeLength, edgeLength, -edgeLength,
        -edgeLength, edgeLength, edgeLength,
        edgeLength, edgeLength, edgeLength,
        edgeLength, edgeLength, -edgeLength,
        -edgeLength, -edgeLength, -edgeLength,
        -edgeLength, -edgeLength, edgeLength,
        edgeLength, -edgeLength, edgeLength,
        edgeLength, -edgeLength, -edgeLength,
    ];
    const squareElement = [
        0, 1,
        1, 2,
        2, 3,
        3, 0,

        4, 5,
        5, 6,
        6, 7,
        7, 4,

        0, 4,
        1, 5,
        2, 6,
        3, 7,
    ];

    square1 = new Obj3D({
        mat: new Mat({
            program: program1,
            data: {
                'u_PointSize': { type: 'uniform1f', value: nodeSize },
                'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4_1.elements },
                'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
            },
            mode: ['POINTS', 'LINES'],

        }),
        geo: new Geo({
            data: {
                'a_Position': {
                    size: 3,
                    array: new Float32Array(squareNode),
                }
            },
            element: {
                array: new Uint8Array(squareElement)
            },
        }),
    });



    square2 = square1.clone();
    square2.setProgram(program2);
    square2.mat.data['u_ModelM4'].value = modelM4_2.elements;

    square3 = square1.clone();
    square3.setProgram(program3);
    square3.mat.data['u_ModelM4'].value = modelM4_3.elements;



    scene.add(square1);
    scene.add(square2);
    scene.add(square3);
    rend();




    function rend() {
        if (scene.childern.length == 0) return;
        scene.setUniform('u_PvM4', { value: pvM4.elements });
        scene.draw();
    }

    let [set1, set2, set3] = [0, 0, 0];
    (function ani() {
        set1 += 0.001;
        set2 -= 0.002;
        set3 += 0.003;
        var a1 = modelM4_1.clone()
            .multiply(new Matrix4().makeRotationX(set1))
            .multiply(new Matrix4().makeRotationY(set1)).elements;
        var a2 = modelM4_2.clone()
            .multiply(new Matrix4().makeRotationX(set2))
            .multiply(new Matrix4().makeRotationZ(set2)).elements;
        var a3 = modelM4_3.clone()
            .multiply(new Matrix4().makeRotationY(set3))
            .multiply(new Matrix4().makeRotationZ(set3)).elements;
        square1.setUniform('u_ModelM4', { value: a1 })
        square2.setUniform('u_ModelM4', { value: a2 })
        square3.setUniform('u_ModelM4', { value: a3 })
        scene.draw();

        requestAnimationFrame(ani);
    })();



</script>

</html>